﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Drawing;

namespace BoringTodo
{
    public static class Utilities
    {
        /// <summary>
        /// 从绑定列表创建新的绑定列表，同时保持通知功能
        /// </summary>
        public static BindingList<T> CloneBindingList<T>(BindingList<T> original) where T : INotifyPropertyChanged
        {
            return new BindingList<T>(original.ToList());
        }

        /// <summary>
        /// 将日期格式化为指定的格式
        /// </summary>
        public static string FormatDate(DateTime? date, string format = null)
        {
            if (!date.HasValue)
                return string.Empty;
                
            format = format ?? Constants.DateFormat;
            return date.Value.ToString(format);
        }

        /// <summary>
        /// 将日期时间格式化为指定的格式
        /// </summary>
        public static string FormatDateTime(DateTime? dateTime, string format = null)
        {
            if (!dateTime.HasValue)
                return string.Empty;
                
            format = format ?? Constants.DateTimeFormat;
            return dateTime.Value.ToString(format);
        }

        /// <summary>
        /// 尝试解析日期字符串，失败时返回null
        /// </summary>
        public static DateTime? TryParseDate(string dateStr)
        {
            if (string.IsNullOrWhiteSpace(dateStr))
                return null;
                
            if (DateTime.TryParse(dateStr, CultureInfo.CurrentCulture, DateTimeStyles.None, out DateTime result))
                return result;
                
            return null;
        }

        /// <summary>
        /// 安全地将对象转换为字符串，处理null值
        /// </summary>
        public static string SafeToString(object value)
        {
            return value?.ToString() ?? string.Empty;
        }

        /// <summary>
        /// 为DataGridView设置标准列宽和样式
        /// </summary>
        public static void ConfigureDataGridView(DataGridView dgv)
        {
            if (dgv == null)
                return;
                
            // 设置基本属性
            dgv.AllowUserToAddRows = false;
            dgv.AllowUserToDeleteRows = false;
            dgv.AllowUserToResizeRows = false;
            dgv.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
            dgv.MultiSelect = false;
            dgv.ReadOnly = true;
            dgv.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.AllCells;
            dgv.RowHeadersVisible = false;
            
            // 设置列宽
            if (dgv.Columns.Count >= 4)
            {
                // 描述列占50%
                dgv.Columns[0].Width = (int)(dgv.Width * 0.5);
                // 备注列占30%
                dgv.Columns[1].Width = (int)(dgv.Width * 0.3);
                // 日期列各占10%
                dgv.Columns[2].Width = (int)(dgv.Width * 0.1);
                dgv.Columns[3].Width = (int)(dgv.Width * 0.1);
                
                // 设置列格式
                foreach (DataGridViewColumn col in dgv.Columns)
                {
                    col.AutoSizeMode = DataGridViewAutoSizeColumnMode.None;
                    col.DefaultCellStyle.WrapMode = DataGridViewTriState.True;
                }
            }
        }

        /// <summary>
        /// 显示一个确认对话框，返回用户是否确认
        /// </summary>
        public static bool ConfirmDialog(string message, string title = "确认")
        {
            return MessageBox.Show(
                message,
                title,
                MessageBoxButtons.YesNo,
                MessageBoxIcon.Question,
                MessageBoxDefaultButton.Button2
            ) == DialogResult.Yes;
        }

        /// <summary>
        /// 显示错误对话框
        /// </summary>
        public static void ShowError(string message, string title = "错误")
        {
            MessageBox.Show(
                message,
                title,
                MessageBoxButtons.OK,
                MessageBoxIcon.Error
            );
        }

        /// <summary>
        /// 显示信息对话框
        /// </summary>
        public static void ShowInfo(string message, string title = "信息")
        {
            MessageBox.Show(
                message,
                title,
                MessageBoxButtons.OK,
                MessageBoxIcon.Information
            );
        }

        /// <summary>
        /// 安全地删除文件，不抛出异常
        /// </summary>
        public static bool SafeDeleteFile(string filePath)
        {
            try
            {
                if (File.Exists(filePath))
                {
                    File.Delete(filePath);
                    return true;
                }
                return false;
            }
            catch (Exception ex)
            {
                Logger.LogError($"删除文件失败: {filePath}", ex);
                return false;
            }
        }

        /// <summary>
        /// 尝试将文本复制到剪贴板
        /// </summary>
        public static bool CopyToClipboard(string text)
        {
            try
            {
                if (!string.IsNullOrEmpty(text))
                {
                    Clipboard.SetText(text);
                    return true;
                }
                return false;
            }
            catch (Exception ex)
            {
                Logger.LogError("复制到剪贴板失败", ex);
                return false;
            }
        }

        /// <summary>
        /// 为控件添加工具提示
        /// </summary>
        public static void AddToolTip(Control control, string tipText)
        {
            if (control == null || string.IsNullOrEmpty(tipText))
                return;
                
            ToolTip tip = new ToolTip();
            tip.SetToolTip(control, tipText);
        }

        /// <summary>
        /// 扩展方法：向BindingList安全地添加项目
        /// </summary>
        public static void AddSafe<T>(this BindingList<T> list, T item)
        {
            if (list == null || item == null)
                return;
                
            list.Add(item);
        }

        /// <summary>
        /// 扩展方法：从BindingList安全地移除项目
        /// </summary>
        public static bool RemoveSafe<T>(this BindingList<T> list, T item)
        {
            if (list == null || item == null)
                return false;
                
            if (list.Contains(item))
            {
                list.Remove(item);
                return true;
            }
            
            return false;
        }

        // 克隆一个BindingList<T>
        public static BindingList<T> Clone<T>(BindingList<T> listToClone) where T : ICloneable
        {
            BindingList<T> result = new BindingList<T>();
            foreach (T item in listToClone)
            {
                result.Add((T)item.Clone());
            }
            return result;
        }

        // 格式化日期时间为易读字符串
        public static string FormatDateTime(DateTime? dateTime)
        {
            if (!dateTime.HasValue)
                return "";
                
            DateTime dt = dateTime.Value;
            
            // 如果是今天
            if (dt.Date == DateTime.Today)
                return "今天 " + dt.ToString("HH:mm");
                
            // 如果是昨天
            if (dt.Date == DateTime.Today.AddDays(-1))
                return "昨天 " + dt.ToString("HH:mm");
                
            // 如果是明天
            if (dt.Date == DateTime.Today.AddDays(1))
                return "明天 " + dt.ToString("HH:mm");
                
            // 如果是本周
            if (dt > DateTime.Today.AddDays(-7) && dt < DateTime.Today.AddDays(7))
                return dt.ToString("dddd HH:mm", new CultureInfo("zh-CN"));
                
            // 其他日期
            return dt.ToString("yyyy-MM-dd HH:mm");
        }

        // 尝试将字符串解析为日期时间
        public static bool TryParseDateTime(string input, out DateTime result)
        {
            return DateTime.TryParse(input, out result);
        }

        // 为DataGridView启用双缓冲以优化性能
        public static void DoubleBuffered(this DataGridView dgv, bool setting)
        {
            Type dgvType = dgv.GetType();
            System.Reflection.PropertyInfo pi = dgvType.GetProperty("DoubleBuffered", 
                System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
            pi.SetValue(dgv, setting, null);
        }
        
        // 显示自定义消息框
        public static DialogResult ShowMessageBox(string message, string title, MessageBoxButtons buttons, MessageBoxIcon icon)
        {
            return MessageBox.Show(message, title, buttons, icon);
        }
    }
}
